#include"../../inc/net/Threadpool.h"
#include<functional>
#include<vector>
#include<memory>


namespace SC
{
    Threadpool::Threadpool(size_t capacity, size_t queuesize)
    : _capacity(capacity), _queuesize(queuesize), _taskqueue(queuesize), _isExit(false)
    {
        _threads.reserve(capacity);
    }

    Threadpool::~Threadpool()
    {
        if(!_isExit)
            stop();
    }

    void Threadpool::start()
    {
        for(size_t idx = 0; idx != _capacity; idx++)
        {
            std::unique_ptr<Thread> ptr(new Thread(
                std::bind(&Threadpool::threadFunc, 
                this)
            ));
            _threads.push_back(std::move(ptr));
        }

        for(auto &thread : _threads)
            thread->start();
    }

    void Threadpool::stop()
    {
        if(!_isExit)
        {
            while(!_taskqueue.isEmpty())
                ::sleep(1);
            
            _taskqueue.exit();

            for(auto &thread : _threads)
                thread->join();
        }
    }

    void Threadpool::addTask(Task&& task)
    {
        _taskqueue.push(std::move(task));
    }

    Task Threadpool::getTask()
    {
        return _taskqueue.pop();
    }

    void Threadpool::threadFunc()
    {
        while(!_isExit)
        {
            Task task = getTask();
            if(task)
                task();
        }
    }
}